﻿import flash.geom.Point;
dynamic class SelfEditer extends MovieClip{
	public static var EDITLIST:Array=[];
	public var conR:Number = 4;
	public var conL:Number = 6;
	public var conColorLine:Number = 0;
	public var conColorFull:Number = 0x00eeff;
	public var offset:Number = 10;
	
	public var canRotate:Boolean = true;
	public var canScale:Boolean = false;
	public var Enable:Boolean = true;
	
	private var showControlType:String="auto";
	private var editTag:MovieClip=null;
	private var controlmc:MovieClip;
	private var con1:MovieClip;
	private var con2:MovieClip;
	private var con3:MovieClip;
	private var con4:MovieClip;
	private var con5:MovieClip;
	private var con6:MovieClip;
	private var con7:MovieClip;
	private var con8:MovieClip;
	
	private var linePoint:Array;
	
	private var moveing:Boolean = false;
	private var controling:Boolean = false;
	private var controltype:String = "none";
	private var contrlHandler:MovieClip;
	private var MouseDownPoint:Point;
	
	
	
	public function SelfEditer(tag:MovieClip) {
		editTag = tag;
		if (editTag != null) {
			EDITLIST.push(editTag);
		}
		linePoint = [];
		Mouse.addListener(this);
	}
	private function checkList(tag:MovieClip, add:Boolean) {
		if (add == undefined) {
			add = true;
		}
		for (var i in EDITLIST) {
			if (EDITLIST[i] == null || EDITLIST[i] == undefined || EDITLIST[i].toString() == "") {
				delete EDITLIST[i];
				continue;
			}
			if (EDITLIST[i] == tag) {
				if (add) {
					return;
				}else{
					EDITLIST.splice(i, 1);
				}
			}
		}
		if (add) {
			EDITLIST.push(tag);
		}
	}
	public function removeMovieClip():Void 
	{
		this.editTag.stopDrag();
		Mouse.removeListener(this);
		super.removeMovieClip();
	}
	private function getTop(hit:Boolean):MovieClip {
		if (hit == undefined) {
			hit = true;
		}
		var topMc:MovieClip=this.editTag;
		for (var i in EDITLIST) {
			var hited:Boolean = false;
			hited = EDITLIST[i].hitTest(_root._xmouse, _root._ymouse, true);
			if (hit) {
				if(hited){
					if (topMc.getDepth() < EDITLIST[i].getDepth()) {
						topMc = EDITLIST[i];
					}
				}
			}else {
				if (topMc.getDepth() < EDITLIST[i].getDepth()) {
					topMc = EDITLIST[i];
				}
			}
		}
		if (hit) {
			if (topMc.hitTest(_root._xmouse, _root._ymouse, true)) {
				return topMc;
			}else {
				return null;
			}
		}
		return topMc;
	}
	public function init(tag:MovieClip) {
		if (tag != null && editTag != undefined) {
			if (editTag != null && editTag != undefined) {
				controlmc.removeMovieClip();
				checkList(editTag, false);
			}
			editTag = tag;
		}
		if (tag == null && editTag == null) {
			trace("control self");
			editTag = this;
		}
		checkList(editTag, true);
		if (editTag != undefined && editTag != null) {
			controlmc = editTag.createEmptyMovieClip("_controlmc", editTag.getNextHighestDepth());
			
			con1 = controlmc.createEmptyMovieClip("c1", controlmc.getNextHighestDepth());
			con2 = controlmc.createEmptyMovieClip("c2", controlmc.getNextHighestDepth());
			con3 = controlmc.createEmptyMovieClip("c3", controlmc.getNextHighestDepth());
			con4 = controlmc.createEmptyMovieClip("c4", controlmc.getNextHighestDepth());
			con5 = controlmc.createEmptyMovieClip("c5", controlmc.getNextHighestDepth());
			con6 = controlmc.createEmptyMovieClip("c6", controlmc.getNextHighestDepth());
			con7 = controlmc.createEmptyMovieClip("c7", controlmc.getNextHighestDepth());
			con8 = controlmc.createEmptyMovieClip("c8", controlmc.getNextHighestDepth());
			
			var w:Number = editTag._width + offset;
			var h:Number = editTag._height + offset;
			
			con1._x = -w / 2;
			con1._y = -h / 2;
			
			con2._x = 0;
			con2._y = -h / 2;
			
			con3._x = w / 2;
			con3._y = -h / 2;
			
			con4._x = -w / 2;
			con4._y = 0;
			
			con5._x = w / 2;
			con5._y = 0;
			
			con6._x = -w / 2;
			con6._y = h / 2;
			
			con7._x = 0;
			con7._y = h / 2;
			
			con8._x = w / 2;
			con8._y = h / 2;
			
			con1.ct = con2.ct = con3.ct = con4.ct = con5.ct = con6.ct = con7.ct = con8.ct = this;
			linePoint = [con1, con2, con3, con5, con8, con7, con6, con4, con1];
			
			/*
			1  2  3
			4     5
			6  7  8
			*/
			if(canRotate){
				drawR(con1, conR, conColorLine, conColorFull);
				drawR(con3, conR, conColorLine, conColorFull);
				drawR(con6, conR, conColorLine, conColorFull);
				drawR(con8, conR, conColorLine, conColorFull);
			}
			if(canScale){
				drawBox(con2, conL, conColorLine, conColorFull);
				drawBox(con4, conL, conColorLine, conColorFull);
				drawBox(con5, conL, conColorLine, conColorFull);
				drawBox(con7, conL, conColorLine, conColorFull);
			}
			if(canRotate){
				con1.onPress = con3.onPress = con6.onPress = con8.onPress = rotationControlFun;
			}
			con4.bl = editTag._xscale / con4._x;
			con5.bl = editTag._xscale / con5._x;
			
			con2.bl = editTag._yscale / con2._y;
			con7.bl = editTag._yscale / con7._y;
			
			if(canScale){
				con4.onPress = con5.onPress = xscaleControlFun;
				con2.onPress = con7.onPress = yscaleControlFun;
			}
			
			////////////////////////////////////////////////////////////////////////////////////////////////////////
			con1.onReleaseOutside = 
			con2.onReleaseOutside = 
			con3.onReleaseOutside = 
			con4.onReleaseOutside = 
			con5.onReleaseOutside = 
			con6.onReleaseOutside = 
			con7.onReleaseOutside = 
			con8.onReleaseOutside =
			con1.onRelease = 
			con2.onRelease = 
			con3.onRelease = 
			con4.onRelease = 
			con5.onRelease = 
			con6.onRelease = 
			con7.onRelease = 
			con8.onRelease = 
			function() {
				this.ct.controltype = "none";
				this.ct.controling = false;
			}
			////////////////////////////////////////////////////
			drawLine();
		}else {
			editTag = null;
		}
	}
	private function rotationControlFun() {
		this.ct.contrlHandler = this;
		this.ct.controltype = "round";
		this.ct.controling = true;
	}
	private function xscaleControlFun() {
		this.ct.contrlHandler = this;
		this.ct.controltype = "xscale";
		this.ct.controling = true;
	}
	private function yscaleControlFun() {
		this.ct.contrlHandler = this;
		this.ct.controltype = "yscale";
		this.ct.controling = true;
	}
	
	/**
	 * 显示控制点方式
	 * @param	type auto,always,none
	 */
	public function showControl(type:String) {
		if (type == undefined || type == null) {
			type = showControlType;
		}
		switch(type) {
			case "always":
			showControlType = "always";
			controlmc._visible = true;
			break;
			
			case "none":
			showControlType = "none";
			controlmc._visible = false;
			break;
			
			default:
			showControlType = "auto";
			controlmc._visible = true;
			break;
		}
	}
	private function checkEnable():Boolean {
		if (!Enable) {
			this.controling = false;
			this.moveing = false;
			this.ct.controltype = "none";
			this.ct.controling = false;
			this.editTag.stopDrag();
			this.controlmc._visible = false;
		}
		return Enable;
	}
	private function onMouseMove() {
		//trace(this.getTop() + "--" + this.editTag+"="+(this.getTop() == this.editTag));
		
		if ((this.getTop() != this.editTag) && this.controling=="none") {
			this.Enable = false;
		}else {
			this.Enable = true;
			if(this.editTag.hitTest(_root._xmouse,_root._ymouse,true)){
				this.editTag.swapDepths(this.getTop(false));
			}
		}
		if (!checkEnable()) {
			return;
		}
		if (this.controling) {
			this.controlmc._visible = true;	
		}else{
			if (this.editTag != null && !this.moveing) {
				if (this.editTag.hitTest(_root._xmouse, _root._ymouse, true)) {
					if (this.showControlType == "none") {
						this.controlmc._visible = false;
					}else {
						this.controlmc._visible = true;	
					}
				}else {
					if (this.showControlType == "always") {
						this.controlmc._visible = true;	
					}else {
						this.controlmc._visible = false;	
					}
				}
			}
		}
		if (this.controling) {
			switch(this.controltype) {
				case "xscale":
					this.ControlToXScale();
				break;
				case "yscale":
					this.ControlToYScale();
				break;
				case "round":
					this.ControlToRotation();
				break;
			}
		}
	}
	private function ControlToXScale() {
		if (!checkEnable()) return;
		this.MouseDownPoint = new Point(_root._xmouse, _root._ymouse);
		this.editTag._xscale = 100;
		this.editTag._xscale = this.editTag._xmouse * this.contrlHandler.bl;
	}
	private function ControlToYScale() {
		if (!checkEnable()) return;
		this.MouseDownPoint = new Point(_root._xmouse, _root._ymouse);
		this.editTag._yscale = 100;
		this.editTag._yscale = this.editTag._ymouse * this.contrlHandler.bl;
	}
	private function ControlToRotation() {
		if (!checkEnable()) return;
		var ct:Point = new Point(this.editTag._x, this.editTag._y);
		this.editTag._parent.localToGlobal(ct);
		var aold:Number = Math.atan2(this.MouseDownPoint.y - ct.y, this.MouseDownPoint.x - ct.x);
		var anew:Number = Math.atan2(_root._ymouse - ct.y, _root._xmouse - ct.x);
		this.editTag._rotation += (anew - aold) * 180 / Math.PI;
		this.MouseDownPoint = new Point(_root._xmouse, _root._ymouse);
	}
	private function onMouseDown() {
		if (!checkEnable()) return;
		this.MouseDownPoint = new Point(_root._xmouse, _root._ymouse);
		if (this.editTag != null && !this.checkControl()) {
			
			if (this.editTag.hitTest(_root._xmouse, _root._ymouse, true)) {
				trace(getTop(true));
				//trace(this+"????")
				this.moveing = true;
				this.editTag.startDrag();
			}
		}
	}
	private function onMouseUp() {
		if (this.editTag != null) {
			this.moveing = false;
			this.editTag.stopDrag();
		}
	}
	private function checkControl():Boolean {
		for (var i:Number = 0; i < linePoint.length; i++) {
			if (linePoint[i].hitTest(_root._xmouse, _root._ymouse)) {
				return true;
			}
		}
		return false;
	}
	
	private function drawLine() {
		if (linePoint.length <=0) {
			return;
		}
		controlmc.lineStyle(0, 0, 20);
		controlmc.beginFill(0xffffff, 10);
		controlmc.moveTo(linePoint[0]._x, linePoint[0]._y);
		for (var i = 1; i < linePoint.length; i++) {
			controlmc.lineTo(linePoint[i]._x, linePoint[i]._y);
		}
		controlmc.endFill();
	}
	
	private function drawR(mc:MovieClip,R:Number,colorLine:Number,colorFull:Number) {
		mc.lineStyle(0, colorLine, 90);
		mc.beginFill(colorFull, 80);
		mc.moveTo(0, -R);
		mc.curveTo(R, -R, R, 0);
		mc.curveTo(R, R, 0, R);
		mc.curveTo( -R, R, -R, 0);
		mc.curveTo( -R, -R, 0, -R);
		mc.endFill();
	}
	private function drawBox(mc:MovieClip,L:Number,colorLine:Number,colorFull:Number) {
		mc.lineStyle(0, colorLine, 90);
		mc.beginFill(colorFull, 80);
		mc.moveTo( -L / 2, -L / 2);
		mc.lineTo(L / 2, -L / 2);
		mc.lineTo(L / 2, L / 2);
		mc.lineTo( -L / 2, L / 2);
		mc.lineTo( -L / 2, -L / 2);
		mc.endFill();
	}
}